package com.rnkrsoft.suyan.config.server.services.impl;

import com.rnkrsoft.framework.orm.Pagination;
import com.rnkrsoft.suyan.config.internal.enums.EnvironmentTypeEnum;
import com.rnkrsoft.suyan.config.internal.enums.FileStatusEnum;
import com.rnkrsoft.suyan.config.protocol.v2.ConfigResponseCode;
import com.rnkrsoft.suyan.config.server.config.bo.*;
import com.rnkrsoft.suyan.config.server.config.dao.*;
import com.rnkrsoft.suyan.config.server.config.entity.*;
import com.rnkrsoft.suyan.config.server.services.file.domains.*;
import com.rnkrsoft.suyan.config.server.services.file.services.FileService;
import com.rnkrsoft.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

/**
 * Created by woate on 2019/5/19.
 */
@Service
public class FileServiceImpl implements FileService {
    @Autowired
    ProjectInfoDAO projectDAO;
    @Autowired
    VersionInfoDAO versionInfoDAO;
    @Autowired
    EnvironmentInfoDAO environmentDAO;
    @Autowired
    MachineInfoDAO machineDAO;
    @Autowired
    FileInfoDAO fileDAO;

    @Override
    public CreateFileResponse create(CreateFileRequest request) {
        CreateFileResponse response = new CreateFileResponse();
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(request.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        List<FileInfoEntity> fileEntities = fileDAO.selectAnd(FileInfoEntity.builder()
                        .machineId(machineEntity.getMachineId())
                        .fileName(request.getFileName())
                        .build()
        );
        if (!fileEntities.isEmpty()) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        FileInfoEntity fileEntity = FileInfoEntity.builder()
                .projectId(machineEntity.getProjectId())
                .environmentId(machineEntity.getEnvironmentId())
                .machineId(machineEntity.getMachineId())
                .fileName(request.getFileName())
                .filePath(request.getFilePath())
                .realFileName(request.getRealFileName())
                .fileEncrypt(request.getFileEncrypt())
                .fileDesc(request.getFileDesc())
                .fileFingerprint(UUID.randomUUID().toString())
                .fileVersion(1)
                .fileStatus(FileStatusEnum.NORMAL.getCode())
                .build();
        fileDAO.insertSelective(fileEntity);
        response.setFileId(fileEntity.getFileId());
        return response;
    }

    @Override
    public ToUpdateFileResponse toUpdate(ToUpdateFileRequest request) {
        ToUpdateFileResponse response = new ToUpdateFileResponse();
        FileInfoEntity fileEntity = fileDAO.selectByPrimaryKey(request.getFileId());
        if (fileEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(fileEntity.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        EnvironmentInfoEntity environmentEntity = environmentDAO.selectByPrimaryKey(machineEntity.getEnvironmentId());
        if (environmentEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        VersionInfoEntity versionInfoEntity = versionInfoDAO.selectByPrimaryKey(environmentEntity.getVersionId());
        if (versionInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        ProjectInfoEntity projectInfoEntity = projectDAO.selectByPrimaryKey(versionInfoEntity.getProjectId());
        if (projectInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }

        response.setProject(projectInfoEntity.getProjectDesc() + "(" + projectInfoEntity.getGroupId() + ":" + projectInfoEntity.getArtifactId() + ":" + versionInfoEntity.getVersion() + ")");
        response.setEnvironment(environmentEntity.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(environmentEntity.getEnvironmentType()).getDesc() + ")");
        response.setMachine(machineEntity.getMachineName());
        response.setFileId(fileEntity.getFileId());
        response.setFilePath(fileEntity.getFilePath());
        response.setFileName(fileEntity.getFileName());
        response.setRealFileName(fileEntity.getRealFileName());
        response.setFileEncrypt(fileEntity.getFileEncrypt());
        response.setFileFingerprint(fileEntity.getFileFingerprint());
        response.setFileStatus(fileEntity.getFileStatus());
        response.setFileDesc(fileEntity.getFileDesc());
        return response;
    }

    @Override
    public UpdateFileResponse update(UpdateFileRequest request) {
        UpdateFileResponse response = new UpdateFileResponse();
        FileInfoEntity fileEntity = fileDAO.selectByPrimaryKey(request.getFileId());
        if (fileEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        fileEntity.setRealFileName(request.getRealFileName());
        fileEntity.setFilePath(request.getFilePath());
        fileEntity.setFileName(request.getFileName());
        fileEntity.setRealFileName(request.getRealFileName());
        fileEntity.setFileEncrypt(request.getFileEncrypt());
        fileEntity.setFileVersion(fileEntity.getFileVersion() + 1);
        fileEntity.setFileDesc(request.getFileDesc());
        int dotIndex = request.getFileName().lastIndexOf(".");
        String suffix = request.getFileName().substring(dotIndex + 1);
        fileEntity.setFileSuffix(suffix);
        fileEntity.setFileStatus(request.getFileStatus());
        fileDAO.updateByPrimaryKeySelective(fileEntity);
        return response;
    }

    @Override
    public DeleteFileResponse delete(DeleteFileRequest request) {
        DeleteFileResponse response = new DeleteFileResponse();
        FileInfoEntity fileEntity = fileDAO.selectByPrimaryKey(request.getFileId());
        if (fileEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        fileDAO.deleteByPrimaryKey(request.getFileId());
        return response;
    }

    @Override
    public ViewFileResponse view(ViewFileRequest request) {
        ViewFileResponse response = new ViewFileResponse();
        FileInfoEntity fileEntity = fileDAO.selectByPrimaryKey(request.getFileId());
        if (fileEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(fileEntity.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        EnvironmentInfoEntity environmentEntity = environmentDAO.selectByPrimaryKey(machineEntity.getEnvironmentId());
        if (environmentEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        VersionInfoEntity versionInfoEntity = versionInfoDAO.selectByPrimaryKey(environmentEntity.getVersionId());
        if (versionInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        ProjectInfoEntity projectInfoEntity = projectDAO.selectByPrimaryKey(versionInfoEntity.getProjectId());
        if (projectInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        response.setProject(projectInfoEntity.getProjectDesc() + "(" + projectInfoEntity.getGroupId() + ":" + projectInfoEntity.getArtifactId() + ":" + versionInfoEntity.getVersion() + ")");
        response.setEnvironment(environmentEntity.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(environmentEntity.getEnvironmentType()).getDesc() + ")");
        response.setMachine(machineEntity.getMachineName());
        response.setFileId(fileEntity.getFileId());
        response.setFilePath(fileEntity.getFilePath());
        response.setFileName(fileEntity.getFileName());
        response.setRealFileName(fileEntity.getRealFileName());
        response.setFileFingerprint(fileEntity.getFileFingerprint());
        response.setFileStatus(fileEntity.getFileStatus());
        response.setFileDesc(fileEntity.getFileDesc());
        return response;
    }

    @Override
    public QueryFileResponse query(QueryFileRequest request) {
        QueryFileResponse response = new QueryFileResponse();
        Pagination<QueryFileInfoBO> pagination = new Pagination<QueryFileInfoBO>(request.getPagination().getPageSize(), request.getPagination().getPageNo());
        if (StringUtils.isNotBlank(request.getProjectId())) {
            pagination.getParams().put("projectId", request.getProjectId());
        }
        if (StringUtils.isNotBlank(request.getEnvironmentType())) {
            pagination.getParams().put("environmentType", request.getEnvironmentType());
        }
        if (StringUtils.isNotBlank(request.getEnvironmentName())) {
            pagination.getParams().put("environmentName", request.getEnvironmentName());
        }
        if (StringUtils.isNotBlank(request.getMachineName())) {
            pagination.getParams().put("machineName", request.getMachineName());
        }
        if (StringUtils.isNotBlank(request.getFilePath())) {
            pagination.getParams().put("filePath", request.getFilePath());
        }
        if (StringUtils.isNotBlank(request.getFileName())) {
            pagination.getParams().put("fileName", request.getFileName());
        }

        if (StringUtils.isNotBlank(request.getFileDesc())) {
            pagination.getParams().put("fileDesc", request.getFileDesc());
        }
        fileDAO.selectFilePage(pagination);
        response.getPagination().setPageSize(request.getPagination().getPageSize());
        response.getPagination().setPageNo(request.getPagination().getPageNo());
        response.getPagination().setTotal(pagination.getTotal());
        response.getPagination().setPageNum(pagination.getPageNum());
        for (QueryFileInfoBO record : pagination.getRecords()) {
            response.getRecords().add(QueryFileRecord.builder()
                            .fileId(record.getFileId())
                            .project(record.getProjectDesc() + "(" + record.getGroupId() + ":" + record.getArtifactId() + ":" + record.getVersion() + ")")
                            .environment(record.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(record.getEnvironmentType()).getDesc() + ")")
                            .machine(record.getMachineName())
                            .filePath(record.getFilePath())
                            .fileName(record.getFileName())
                            .fileVersion(record.getFileVersion())
                            .build()
            );
        }
        return response;
    }

    @Override
    public ListFileResponse listFileByMachine(ListFileByMachineRequest request) {
        ListFileResponse response = new ListFileResponse();
        List<FileInfoEntity> fileInfoEntities = fileDAO.selectAnd(FileInfoEntity.builder().machineId(request.getMachineId()).build());
        for (FileInfoEntity fileInfoEntity : fileInfoEntities) {
            response.getFiles().add(ListFileRecord.builder()
                            .filePath(fileInfoEntity.getFilePath())
                            .fileName(fileInfoEntity.getFileName())
                            .fileEncrypt(fileInfoEntity.getFileEncrypt())
                            .fileDesc(fileInfoEntity.getFileDesc())
                            .fileVersion(fileInfoEntity.getFileVersion())
                            .build()
            );
        }
        return response;
    }

    @Override
    public GrantFileResponse grant(GrantFileRequest request) {
        GrantFileResponse response = new GrantFileResponse();
        return response;
    }
}
